; Disassembly of the file "z:\ramdisk\home\knoppix\CoBra Project\Software\ROM\EPROM Images - Saved from programmed EPROMs\EPROM_2K_COBRA_64K.BIN" ; ; CPU Type: Z80 ; ; Created with dZ80 2.0 ; ; on Thursday, 04 of April 2013 at 07:27 PM ; ; This code creates and uses a data block starting at F000: ; F000 9C (set at line 0004) CTC-0 INT. SVC. ADDR ; F001 06 (set at line 0004) CTC-0 INT. SVC. ADDR ; F002 CTC-1 INT. SVC. ADDR ; F003 CTC-1 INT. SVC. ADDR ; F004 CTC-2 INT. SVC. ADDR ; F005 CTC-2 INT. SVC. ADDR ; F006 CTC-3 INT. SVC. ADDR ; F007 CTC-3 INT. SVC. ADDR ; F008 00 (set at line 0401) storage start addr for bytes to be read from FDD (lower half) ; F009 80 (set at line 0401) storage start addr for bytes to be read from FDD (upper half) ; F00A CTC-2 time constant ; F00B CTC-1 time constant ; F00C 00 (set at line 03E4) 8272 command byte 1 ; F00D 00 (set at line 03E4) 8272 command byte 2 ; F00E 00 (set at line 03E4) 8272 command byte 3 (usually C, track no.) ; F00F 00 (set at line 03E4) 8272 command byte 4 (usually H, head no.) ; F010 01 (set at line 03E4) 8272 command byte 5 (usually R, current sector no.) ; F011 00 (set at line 03E4) 8272 command byte 6 (usually N, bytes per sector) ; F012 1A (set at line 03E4) 8272 command byte 7 (usually EOT, last sector no. on cylinder, here 26) ; F013 06 (set at line 03E4) 8272 command byte 8 (usually GPL, Gap 3 length) ; F014 80 (set at line 03E4) 8272 command byte 9 (usually DTL, Data Length, user sector size if N=00, here 128) ; F015 result byte 1 from 8272 commands ; F016 result byte 2 from 8272 commands ; F017 result byte 3 from 8272 commands ; F018 result byte 4 from 8272 commands (C) ; F019 result byte 5 from 8272 commands (H) ; F01A result byte 6 from 8272 commands (R) ; F01B result byte 7 from 8272 commands (N) ; F01C 1A if FM or 28 if MFM (set in PARAM_SET) ; F01D set to 00 in PARAM_SET ; F01E current storage addr for next byte to be read from FDD after last 8272_CMD (lower half) ; F01F current storage addr for next byte to be read from FDD after last 8272_CMD (upper half) ; F020 Read ID first result byte, ST0, AND-ed with C0h (00 = Read ID ok) see line 040A ; F021 00 if zero or formatted, 02 else (see line 042F) 0000 3E80 LD A,$80 0002 ED4F LD R,A ; set bit 7 of R to 1 to maintain startup config 0004 219C06 LD HL,$069C ; ---@@@0006:06->0E 0007 2200F0 LD ($F000),HL ; (F000) <- 069C (CTC-0 Int. Vector for non-Result-Phase commands) 000A 31FFFF LD SP,$FFFF ; stack at FFFF 000D 26C0 * LD H,$C0 000F 2E00 * LD L,$00 0011 3600 LD (HL),$00 ; (C000) <- 00 (video mem base) 0013 54 * LD D,H 0014 1E01 * LD E,$01 ; DE <- C001 0016 01FF1A LD BC,$1AFF ; serial video mem size 0019 EDB0 LDIR ; erase serial video mem (with 00) 001B 3E92 LD A,$92 001D D3DF OUT ($DF),A ; write DF to 8255 Control Register 001F 3E40 LD A,$40 0021 D3FE OUT ($FE),A ; write 40 to 8255 Port C ; ############### GRAPHIC LOGO ################## 0023 01FE78 LD BC,$78FE 0026 26D9 * LD H,$D9 0028 2E00 * LD L,$00 ; HL = D900 002A 0608 LD B,$08 ; BC = 08FE 002C C5 PUSH BC ; BC on stack <--- <--- <--- <--- <--- <--- <--- <--- <-- 002D 01050C LD BC,$0C05 ; B = 0C as counter | 0030 71 LD (HL),C ; (D900) <- 05 (INK=5, PAPER=0) | 0031 23 INC HL ; do this for the first 12 bytes of the | 0032 10FC DJNZ $0030 ; color attr of middle third of screen | 0034 010314 LD BC,$1403 ; B = 14 as counter | 0037 71 LD (HL),C ; (D90C) <- 03 (INK=3, PAPER=0) | 0038 23 INC HL ; do this for the next 20 bytes of the | 0039 10FC DJNZ $0037 ; color attr of middle third of screen | 003B C1 POP BC ; BC = 08FE (B=08 used as counter) | 003C 10EE DJNZ $002C ; repeat 8 times for all 8 rows of middle third ---> -->| 003E D9 EXX 003F 212201 LD HL,$0122 ; HL' used as pointer to data block start address (0122) ---@@@0041:01->09 0042 D9 EXX 0043 26CB * LD H,$CB 0045 2EB9 * LD L,$B9 ; HL=CBB9, address within serial video RAM, middle third of screen 0047 11FE01 LD DE,$01FE ; data to be written in there 004A 3E04 LD A,$04 004C 0609 LD B,$09 004E C5 PUSH BC ; <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- 004F 47 LD B,A ; | 0050 72 LD (HL),D ; write "01" at CBB9 <--- <--- <- <--- <- | 0051 23 INC HL ; | | | 0052 73 LD (HL),E ; write "FE" at CBBA | | | 0053 D9 EXX ; | | | 0054 7E LD A,(HL) ; read first byte of data (FF) | | | 0055 23 INC HL ; increment pointer (HL'=0189) | | | 0056 D9 EXX ; | | | 0057 4F LD C,A ; C = data byte | | | 0058 85 ADD A,L ; A = data byte + L = B9 + CY | | | 0059 6F LD L,A ; L = data byte + L | | | 005A 3001 JR NC,$005D ; | | | 005C 24 INC H ; H=CB+1=CC | | | 005D 10F1 DJNZ $0050 ; ---> ---> ---> ---> ---> --->>> | | 005F 41 LD B,C ; | | 0060 D9 EXX ; | | 0061 5E LD E,(HL) ; Read 2 bytes | | 0062 23 INC HL ; of data into | | 0063 56 LD D,(HL) ; DE' register. | | 0064 23 INC HL ; Increment pointer | | 0065 D5 PUSH DE ; | | 0066 D9 EXX ; | | 0067 E1 POP HL ; HL = 2 data bytes | | 0068 CB23 SLA E ; | | 006A CB12 RL D ; | | 006C 30E2 JR NC,$0050 ; ---> ---> ---> ---> ---> ---> ---> --->> | 006E CB1A RR D ; | 0070 CB1B RR E ; | 0072 16FF LD D,$FF ; | 0074 CB22 SLA D ; <---- | 0076 CB13 RL E ; | | 0078 38FA JR C,$0074 ; ----> | 007A 7A LD A,D ; | 007B 2F CPL ; | 007C 57 LD D,A ; | 007D 1EFF LD E,$FF ; | 007F 79 LD A,C ; | 0080 C1 POP BC ; | 0081 10CB DJNZ $004E ; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> 0083 5D * LD E,L 0084 54 * LD D,H 0085 D9 EXX 0086 E5 PUSH HL 0087 D9 EXX 0088 E1 POP HL 0089 060B LD B,$0B 008B C5 PUSH BC ; <--- <--- 008C 47 LD B,A ; | 008D 7E LD A,(HL) ; | 008E 23 INC HL ; | 008F 12 LD (DE),A ; <---- | 0090 13 INC DE ; | | 0091 10FC DJNZ $008F ; ----> | 0093 7E LD A,(HL) ; | 0094 23 INC HL ; | 0095 5E LD E,(HL) ; | 0096 23 INC HL ; | 0097 56 LD D,(HL) ; | 0098 23 INC HL ; | 0099 C1 POP BC ; | 009A 10EF DJNZ $008B ; ---> ---> 009C 010800 LD BC,$0008 ; length of color pattern under logo 009F 118CDA LD DE,$DA8C ; addr of color attr for color pattern under logo (within video mem) 00A2 217A03 LD HL,$037A ; addr of color attr for color pattern under logo (within data block) ---@@@00A4:03->0B 00A5 EDB0 LDIR 00A7 1607 LD D,$07 ; ######### BEGINNING OF ONE SCREEN CYCLE (KBD READ + SCROLL LEFT) ######### 00A9 010000 LD BC,$0000 00AC C5 PUSH BC ; <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <-| 00AD 01FE78 LD BC,$78FE ; B=78 for keyboard test, rows KA15, KA10, KA9, KA8, C=FE for port addr 00B0 ED78 IN A,(C) ; | 00B2 00 NOP ; | 00B3 00 NOP ; | 00B4 C30507 JP $0705 ; jump to keyboard read | ---@@@00B6:07->0F 00B7 1F RRA ; return point from 0705, test column K2 ("M" "E" "D" "X") | 00B8 D2D803 JP NC,$03D8 ; if any key pressed jump to DISK LOADING | ---@@@00BA:03->0B 00BB 1F RRA ; test column K3 ("N" "R" "F" "C") | 00BC D2DF06 JP NC,$06DF ; if any key pressed jump to TAPE LOADING (?) | ---@@@00BE:06->0E 00BF 1F RRA ; test column K4 ("B" "T" "G" "V") | 00C0 D21907 JP NC,$0719 ; if any key pressed jump to TAPE VERIFY (?) | ---@@@00C2:07->0F 00C3 1F RRA ; | 00C4 C1 POP BC ; | 00C5 10E5 DJNZ $00AC ; ---> ---> ---> x256 ---> ---> ---> ---> ---> ---> ---> ---> ->| 00C7 0D DEC C ; C=FF | 00C8 20E2 JR NZ,$00AC ; ---> ---> ---> x256 ---> ---> ---> ---> ---> ---> ---> ---> ->| 00CA 15 DEC D ; | 00CB 20DF JR NZ,$00AC ; ---> ---> ---> x7 ---> ---> ---> ---> ---> ---> ---> ---> ->| 00CD 0620 LD B,$20 00CF C5 PUSH BC ; BC=2000 00D0 CDF100 CALL $00F1 ; call SERIAL VIDEO GRAPHIC SCROLL LEFT 4 PIXELS ---@@@00D2:00->08 00D3 26D9 * LD H,$D9 00D5 2E01 * LD L,$01 ; HL=D901 ######## 00D5-00E7 mid screen attribute scroll left 1 char ######## 00D7 0608 LD B,$08 00D9 C5 PUSH BC ; BC=0800 (B=08 used as row counter) <--- <--- <--- <--- <---| 00DA 011F00 LD BC,$001F ; screen width in chars minus 1 | 00DD 54 * LD D,H ; | 00DE 5D * LD E,L ; DE=D901 | 00DF 1D DEC E ; DE=D900 (start of row 1 (of 8) of attr's for middle third of screen) 00E0 1A LD A,(DE) ; copy the first attr byte on the row | 00E1 EDB0 LDIR ; shift 31 attribute bytes left, first byte overwritten | 00E3 12 LD (DE),A ; save the former first byte into the last on the row | 00E4 2C INC L ; HL now points to first char on next row | 00E5 1C INC E ; DE now points to last char on row | 00E6 C1 POP BC ; POP back the row counter | 00E7 10F0 DJNZ $00D9 ; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ->| ######## 00E9 CDF100 CALL $00F1 ; call SERIAL VIDEO GRAPHIC SCROLL LEFT 4 PIXELS ---@@@00EB:00->08 00EC C1 POP BC 00ED 10E0 DJNZ $00CF 00EF 18B6 JR $00A7 ; ######### END OF ONE SCREEN CYCLE (KBD READ + SCROLL LEFT) ######### 00F1 0604 LD B,$04 ; ######### SERIAL VIDEO GRAPHIC SCROLL LEFT 4 PIXELS ########## 00F3 C5 PUSH BC ; <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <----| 00F4 26CF * LD H,$CF ; | 00F6 2EFF * LD L,$FF ; HL=CFFF (end address of middle third of screen serial video mem) | 00F8 0608 LD B,$08 ; | 00FA C5 PUSH BC ; char line counter <--- <--- <--- <--- <--- <--- <--- <--- <-----| | 00FB 0608 LD B,$08 ; | | 00FD C5 PUSH BC ; pixel row counter on a char line <--- <--- <--- <-----| | | 00FE 54 * LD D,H ; | | | 00FF 5D * LD E,L ; DE=CFFF (store the end address of crt pixel row) | | | 0100 0620 LD B,$20 ; char counter for one screen row | | | 0102 37 SCF ; CY=1 (last pixel on row will show as INK) | | | 0103 CB16 RL (HL) ; rotate left through CY <--- <--- <--- <--- <--| | | | 0105 2B DEC HL ; HL=address counter | | | | 0106 10FB DJNZ $0103 ; shift all bytes on a row 1 bit left ---> ---->| | | | 0108 3803 JR C,$010D ; if first bit on row was 1, skip 3 lines | | | 010A 1A LD A,(DE) ; (the last byte on crt pixel row) | | | 010B 3D DEC A ; -1 (when first bit on row was 0) | | | 010C 12 LD (DE),A ; save corrected value | | | 010D C1 POP BC ; pixel row counter on a char line | | | 010E 37 * SCF ; | | | 010F 3F * CCF ; CY=0 | | | 0110 11E000 LD DE,$00E0 ; 7 rows x 32 chars to get to end of prev. pixel row on same char line | 0113 ED52 SBC HL,DE ; HL=HL-DE-CY (end of prev pixel row on same char line) | | | 0115 10E6 DJNZ $00FD ; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> --->| | | ; after 1 char row is fully shifted, HL points to last byte | | ; on the first pixel row of the previous char row, minus E0. | | ; we need to get to last byte on last pixel row of prev char row. | | 0117 01E007 LD BC,$07E0 ; 20h x 8 x 7 + E0h (E0 is correction to last subtraction) | | 011A 09 ADD HL,BC ; HL now points to last byte on last pixel row of prev char row | | 011B C1 POP BC ; char line counter | | 011C 10DC DJNZ $00FA ; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> --->| | 011E C1 POP BC ; pixel displacement counter | 011F 10D2 DJNZ $00F3 ; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---->| 0121 C9 RET ; ############ GRAPHIC DATA BLOCK ########### 0122 FF DB $FF 0123 E0 DB $E0 0124 FF DB $FF 0125 1F DB $1F 0126 B1 DB $B1 0127 C8 DB $C8 0128 45 DB $45 0129 B9 DB $B9 012A 22 DB $22 012B 02 DB $02 012C 1F DB $1F 012D A2 DB $A2 012E 16 DB $16 012F 22 DB $22 0130 02 DB $02 0131 1F DB $1F 0132 A2 DB $A2 0133 16 DB $16 0134 25 DB $25 0135 15 DB $15 0136 09 DB $09 0137 75 DB $75 0138 43 DB $43 0139 25 DB $25 013A BC DB $BC 013B 02 DB $02 013C 19 DB $19 013D 25 DB $25 013E BC DB $BC 013F 02 DB $02 0140 19 DB $19 0141 07 DB $07 0142 1D DB $1D 0143 D9 DB $D9 0144 07 DB $07 0145 1D DB $1D 0146 0C DB $0C 0147 9A DB $9A 0148 C8 DB $C8 0149 07 DB $07 014A A5 DB $A5 014B 90 DB $90 014C FF DB $FF 014D 88 DB $88 014E FF DB $FF 014F E5 DB $E5 0150 FF DB $FF 0151 FF DB $FF 0152 31 DB $31 0153 07 DB $07 0154 0C DB $0C 0155 82 DB $82 0156 C8 DB $C8 0157 FF DB $FF 0158 FF DB $FF 0159 FF DB $FF 015A 6D DB $6D 015B 7F DB $7F 015C 09 DB $09 015D 07 DB $07 015E F7 DB $F7 015F 07 DB $07 0160 DF DB $DF 0161 FF DB $FF 0162 09 DB $09 0163 CC DB $CC 0164 C8 DB $C8 0165 7B DB $7B 0166 92 DB $92 0167 FF DB $FF 0168 FF DB $FF 0169 EB DB $EB 016A FF DB $FF 016B FF DB $FF 016C C4 DB $C4 016D 10 DB $10 016E AF DB $AF 016F C8 DB $C8 0170 FC DB $FC 0171 02 DB $02 0172 FC DB $FC 0173 02 DB $02 0174 FC DB $FC 0175 02 DB $02 0176 FC DB $FC 0177 02 DB $02 0178 FC DB $FC 0179 02 DB $02 017A FC DB $FC 017B 02 DB $02 017C 0B DB $0B 017D F3 DB $F3 017E 0B DB $0B 017F 06 DB $06 0180 87 DB $87 0181 C8 DB $C8 0182 C0 DB $C0 0183 FF DB $FF 0184 FF DB $FF 0185 72 DB $72 0186 FF DB $FF 0187 0B DB $0B 0188 46 DB $46 0189 C8 DB $C8 018A 74 DB $74 018B 6E DB $6E 018C 3D DB $3D 018D 52 DB $52 018E 8E DB $8E 018F 9F DB $9F 0190 FE DB $FE 0191 DD DB $DD 0192 FF DB $FF 0193 82 DB $82 0194 11 DB $11 0195 8C DB $8C 0196 C8 DB $C8 0197 62 DB $62 0198 55 DB $55 0199 20 DB $20 019A E1 DB $E1 019B 70 DB $70 019C 8E DB $8E 019D DA DB $DA 019E A3 DB $A3 019F 7A DB $7A 01A0 5F DB $5F 01A1 9F DB $9F 01A2 5F DB $5F 01A3 CC DB $CC 01A4 2A DB $2A 01A5 28 DB $28 01A6 08 DB $08 01A7 0B DB $0B 01A8 62 DB $62 01A9 C8 DB $C8 01AA E5 DB $E5 01AB FF DB $FF 01AC FF DB $FF 01AD 59 DB $59 01AE F7 DB $F7 01AF 07 DB $07 01B0 A5 DB $A5 01B1 70 DB $70 01B2 B6 DB $B6 01B3 D1 DB $D1 01B4 13 DB $13 01B5 D1 DB $D1 01B6 C8 DB $C8 01B7 02 DB $02 01B8 02 DB $02 01B9 01 DB $01 01BA 88 DB $88 01BB 37 DB $37 01BC 07 DB $07 01BD 2E DB $2E 01BE 90 DB $90 01BF 3F DB $3F 01C0 A5 DB $A5 01C1 8B DB $8B 01C2 BF DB $BF 01C3 02 DB $02 01C4 F9 DB $F9 01C5 FF DB $FF 01C6 FF DB $FF 01C7 02 DB $02 01C8 02 DB $02 01C9 08 DB $08 01CA D1 DB $D1 01CB CA DB $CA 01CC 76 DB $76 01CD 90 DB $90 01CE ED DB $ED 01CF 9A DB $9A 01D0 2E DB $2E 01D1 E8 DB $E8 01D2 07 DB $07 01D3 09 DB $09 01D4 CC DB $CC 01D5 C9 DB $C9 01D6 7B DB $7B 01D7 86 DB $86 01D8 78 DB $78 01D9 92 DB $92 01DA EB DB $EB 01DB 9F DB $9F 01DC 27 DB $27 01DD FC DB $FC 01DE 0B DB $0B 01DF AC DB $AC 01E0 C8 DB $C8 01E1 22 DB $22 01E2 0B DB $0B 01E3 F3 DB $F3 01E4 FC DB $FC 01E5 FF DB $FF 01E6 FA DB $FA 01E7 FF DB $FF 01E8 C7 DB $C7 01E9 FF DB $FF 01EA 1C DB $1C 01EB 03 DB $03 01EC BB DB $BB 01ED CD DB $CD 01EE B4 DB $B4 01EF F6 DB $F6 01F0 10 DB $10 01F1 2A DB $2A 01F2 C8 DB $C8 01F3 C6 DB $C6 01F4 54 DB $54 01F5 03 DB $03 01F6 FD DB $FD 01F7 72 DB $72 01F8 38 DB $38 01F9 F5 DB $F5 01FA DC DB $DC 01FB 7B DB $7B 01FC 30 DB $30 01FD 02 DB $02 01FE F8 DB $F8 01FF 32 DB $32 0200 A6 DB $A6 0201 26 DB $26 0202 0C DB $0C 0203 66 DB $66 0204 C8 DB $C8 0205 28 DB $28 0206 FC DB $FC 0207 BB DB $BB 0208 FF DB $FF 0209 DE DB $DE 020A FB DB $FB 020B E4 DB $E4 020C BA DB $BA 020D 08 DB $08 020E FA DB $FA 020F 07 DB $07 0210 01 DB $01 0211 46 DB $46 0212 CF DB $CF 0213 01 DB $01 0214 46 DB $46 0215 CE DB $CE 0216 05 DB $05 0217 CC DB $CC 0218 CA DB $CA 0219 FF DB $FF 021A FA DB $FA 021B 7E DB $7E 021C 45 DB $45 021D 01 DB $01 021E 46 DB $46 021F CC DB $CC 0220 01 DB $01 0221 46 DB $46 0222 CB DB $CB 0223 0C DB $0C 0224 91 DB $91 0225 C8 DB $C8 0226 B6 DB $B6 0227 FD DB $FD 0228 E1 DB $E1 0229 9B DB $9B 022A 7E DB $7E 022B 85 DB $85 022C FD DB $FD 022D FF DB $FF 022E 61 DB $61 022F 79 DB $79 0230 2D DB $2D 0231 0A DB $0A 0232 24 DB $24 0233 C9 DB $C9 0234 6A DB $6A 0235 FC DB $FC 0236 57 DB $57 0237 EC DB $EC 0238 F5 DB $F5 0239 FB DB $FB 023A 08 DB $08 023B 56 DB $56 023C AB DB $AB 023D 02 DB $02 023E CC DB $CC 023F CB DB $CB 0240 BF DB $BF 0241 04 DB $04 0242 ED DB $ED 0243 CA DB $CA 0244 E1 DB $E1 0245 BF DB $BF 0246 DD DB $DD 0247 03 DB $03 0248 D1 DB $D1 0249 CB DB $CB 024A 95 DB $95 024B 29 DB $29 024C 01 DB $01 024D E6 DB $E6 024E C8 DB $C8 024F 0D DB $0D 0250 C3 DB $C3 0251 C8 DB $C8 0252 CD DB $CD 0253 62 DB $62 0254 F3 DB $F3 0255 5A DB $5A 0256 E3 DB $E3 0257 FF DB $FF 0258 A1 DB $A1 0259 40 DB $40 025A 1E DB $1E 025B 4A DB $4A 025C 02 DB $02 025D 59 DB $59 025E 0D DB $0D 025F 8F DB $8F 0260 CA DB $CA 0261 FC DB $FC 0262 02 DB $02 0263 97 DB $97 0264 9B DB $9B 0265 08 DB $08 0266 02 DB $02 0267 09 DB $09 0268 F5 DB $F5 0269 09 DB $09 026A 2A DB $2A 026B 62 DB $62 026C BB DB $BB 026D 01 DB $01 026E E6 DB $E6 026F C8 DB $C8 0270 04 DB $04 0271 F0 DB $F0 0272 CA DB $CA 0273 F8 DB $F8 0274 DD DB $DD 0275 A8 DB $A8 0276 02 DB $02 0277 C3 DB $C3 0278 C9 DB $C9 0279 7F DB $7F 027A 14 DB $14 027B 94 DB $94 027C C8 DB $C8 027D 02 DB $02 027E 5C DB $5C 027F FB DB $FB 0280 A0 DB $A0 0281 FF DB $FF 0282 22 DB $22 0283 02 DB $02 0284 52 DB $52 0285 A9 DB $A9 0286 02 DB $02 0287 19 DB $19 0288 09 DB $09 0289 4D DB $4D 028A A7 DB $A7 028B 09 DB $09 028C ED DB $ED 028D AA DB $AA 028E 02 DB $02 028F 5C DB $5C 0290 0C DB $0C 0291 43 DB $43 0292 C8 DB $C8 0293 B5 DB $B5 0294 EA DB $EA 0295 3F DB $3F 0296 E3 DB $E3 0297 BA DB $BA 0298 40 DB $40 0299 C2 DB $C2 029A FF DB $FF 029B FF DB $FF 029C 11 DB $11 029D FF DB $FF 029E 07 DB $07 029F 43 DB $43 02A0 C9 DB $C9 02A1 E4 DB $E4 02A2 9A DB $9A 02A3 84 DB $84 02A4 AA DB $AA 02A5 7F DB $7F 02A6 02 DB $02 02A7 07 DB $07 02A8 ED DB $ED 02A9 C9 DB $C9 02AA FA DB $FA 02AB 7E DB $7E 02AC BF DB $BF 02AD FF DB $FF 02AE FF DB $FF 02AF 45 DB $45 02B0 17 DB $17 02B1 26 DB $26 02B2 C8 DB $C8 02B3 D4 DB $D4 02B4 98 DB $98 02B5 02 DB $02 02B6 1C DB $1C 02B7 02 DB $02 02B8 DC DB $DC 02B9 02 DB $02 02BA 1C DB $1C 02BB 02 DB $02 02BC 52 DB $52 02BD FD DB $FD 02BE 20 DB $20 02BF FD DB $FD 02C0 8C DB $8C 02C1 02 DB $02 02C2 1C DB $1C 02C3 DF DB $DF 02C4 02 DB $02 02C5 1C DB $1C 02C6 06 DB $06 02C7 ED DB $ED 02C8 11 DB $11 02C9 2A DB $2A 02CA 28 DB $28 02CB C8 DB $C8 02CC 6A DB $6A 02CD 02 DB $02 02CE 1C DB $1C 02CF 02 DB $02 02D0 3C DB $3C 02D1 9F DB $9F 02D2 02 DB $02 02D3 1C DB $1C 02D4 02 DB $02 02D5 3C DB $3C 02D6 05 DB $05 02D7 99 DB $99 02D8 02 DB $02 02D9 1C DB $1C 02DA 02 DB $02 02DB 3C DB $3C 02DC 05 DB $05 02DD 0A DB $0A 02DE 8E DB $8E 02DF 02 DB $02 02E0 1C DB $1C 02E1 02 DB $02 02E2 42 DB $42 02E3 B9 DB $B9 02E4 02 DB $02 02E5 1C DB $1C 02E6 9F DB $9F 02E7 02 DB $02 02E8 3C DB $3C 02E9 02 DB $02 02EA 1C DB $1C 02EB 9F DB $9F 02EC 02 DB $02 02ED 3C DB $3C 02EE 02 DB $02 02EF 1C DB $1C 02F0 9F DB $9F 02F1 02 DB $02 02F2 3C DB $3C 02F3 02 DB $02 02F4 1C DB $1C 02F5 01 DB $01 02F6 E6 DB $E6 02F7 C8 DB $C8 02F8 17 DB $17 02F9 8D DB $8D 02FA C8 DB $C8 02FB 26 DB $26 02FC 02 DB $02 02FD 31 DB $31 02FE 03 DB $03 02FF 38 DB $38 0300 66 DB $66 0301 6D DB $6D 0302 91 DB $91 0303 6D DB $6D 0304 2D DB $2D 0305 63 DB $63 0306 06 DB $06 0307 02 DB $02 0308 63 DB $63 0309 D1 DB $D1 030A 06 DB $06 030B F8 DB $F8 030C FF DB $FF 030D 9F DB $9F 030E 46 DB $46 030F 02 DB $02 0310 15 DB $15 0311 06 DB $06 0312 25 DB $25 0313 C8 DB $C8 0314 BE DB $BE 0315 43 DB $43 0316 FF DB $FF 0317 FB DB $FB 0318 C0 DB $C0 0319 08 DB $08 031A E9 DB $E9 031B C9 DB $C9 031C 3C DB $3C 031D 02 DB $02 031E 3D DB $3D 031F E1 DB $E1 0320 DD DB $DD 0321 9D DB $9D 0322 83 DB $83 0323 29 DB $29 0324 E6 DB $E6 0325 C8 DB $C8 0326 01 DB $01 0327 5F DB $5F 0328 9D DB $9D 0329 01 DB $01 032A 07 DB $07 032B 37 DB $37 032C 1F DB $1F 032D 9D DB $9D 032E 01 DB $01 032F 1D DB $1D 0330 01 DB $01 0331 1D DB $1D 0332 01 DB $01 0333 1F DB $1F 0334 9E DB $9E 0335 01 DB $01 0336 1C DB $1C 0337 01 DB $01 0338 1C DB $1C 0339 01 DB $01 033A 9D DB $9D 033B 01 DB $01 033C 5D DB $5D 033D 01 DB $01 033E 20 DB $20 033F 7C DB $7C 0340 01 DB $01 0341 3E DB $3E 0342 01 DB $01 0343 1C DB $1C 0344 01 DB $01 0345 20 DB $20 0346 27 DB $27 0347 54 DB $54 0348 01 DB $01 0349 5D DB $5D 034A 01 DB $01 034B 20 DB $20 034C 7C DB $7C 034D 01 DB $01 034E 01 DB $01 034F 45 DB $45 0350 C8 DB $C8 0351 C3 DB $C3 0352 01 DB $01 0353 87 DB $87 0354 C8 DB $C8 0355 03 DB $03 0356 01 DB $01 0357 87 DB $87 0358 C9 DB $C9 0359 01 DB $01 035A 01 DB $01 035B 68 DB $68 035C CE DB $CE 035D E0 DB $E0 035E 01 DB $01 035F 67 DB $67 0360 CF DB $CF 0361 07 DB $07 0362 0A DB $0A 0363 03 DB $03 0364 D9 DB $D9 0365 01 DB $01 0366 02 DB $02 0367 27 DB $27 0368 D9 DB $D9 0369 35 DB $35 036A 01 DB $01 036B 47 DB $47 036C D9 DB $D9 036D 15 DB $15 036E 04 DB $04 036F 48 DB $48 0370 D9 DB $D9 0371 02 DB $02 0372 01 DB $01 0373 8B DB $8B 0374 D9 DB $D9 0375 03 DB $03 0376 01 DB $01 0377 AB DB $AB 0378 D9 DB $D9 0379 03 DB $03 037A 07 DB $07 037B 0E DB $0E 037C 15 DB $15 037D 1C DB $1C 037E 23 DB $23 037F 2A DB $2A 0380 31 DB $31 0381 38 DB $38 ; ####### DISK PARAMS BLOCK ####### 0382 00 DB $00 0383 00 DB $00 0384 00 DB $00 0385 00 DB $00 0386 01 DB $01 0387 00 DB $00 0388 1A DB $1A 0389 06 DB $06 038A 80 DB $80 ; ####### FM SECTOR TABLE ####### ; --- 8" floppy, 26 sectors, interleave 6 --- 038B 01 DB $01 ; 1 038C 07 DB $07 ; 7 038D 0D DB $0D ; 13 038E 13 DB $13 ; 19 038F 19 DB $19 ; 25 0390 05 DB $05 ; 5 0391 0B DB $0B ; 11 0392 11 DB $11 ; 17 0393 17 DB $17 ; 23 0394 03 DB $03 ; 3 0395 09 DB $09 ; 9 0396 0F DB $0F ; 15 0397 15 DB $15 ; 21 0398 02 DB $02 ; 2 0399 08 DB $08 ; 8 039A 0E DB $0E ; 14 039B 14 DB $14 ; 20 039C 1A DB $1A ; 26 039D 06 DB $06 ; 6 039E 0C DB $0C ; 12 039F 12 DB $12 ; 18 03A0 18 DB $18 ; 24 03A1 04 DB $04 ; 4 03A2 0A DB $0A ; 10 03A3 10 DB $10 ; 16 03A4 16 DB $16 ; 22 ; ###### MFM SECTOR TABLE ; --- 10 sectors, interleave 3 --- 03A5 01 DB $01 ; 1 03A6 04 DB $04 ; 4 03A7 07 DB $07 ; 7 03A8 0A DB $0A ; 10 03A9 03 DB $03 ; 3 03AA 06 DB $06 ; 6 03AB 09 DB $09 ; 9 03AC 02 DB $02 ; 2 03AD 05 DB $05 ; 5 03AE 08 DB $08 ; 8 ; ###### CP/M loader dir entry 03AF 00 DB $00 ; user no. 03B0 53 DB $53 ; "S" 03B1 59 DB $59 ; "Y" 03B2 53 DB $53 ; "S" 03B3 20 DB $20 ; " " 03B4 20 DB $20 ; " " 03B5 20 DB $20 ; " " 03B6 20 DB $20 ; " " 03B7 20 DB $20 ; " " 03B8 43 DB $43 ; "C" 03B9 4F DB $4F ; "O" 03BA 4D DB $4D ; "M" 03BB DD210000 LD IX,$0000 ; ########## ???????????????? ########## 03BF 110020 LD DE,$2000 03C2 3EFE LD A,$FE 03C4 37 SCF 03C5 CDC204 CALL $04C2 ; strange call !! EX AF,AF';INC B + rest of READ_DISK ---@@@03C7:04->0C 03C8 DD210020 LD IX,$2000 03CC 110020 LD DE,$2000 03CF 3EFE LD A,$FE 03D1 37 SCF 03D2 CDC204 CALL $04C2 ; ---@@@03D4:04->0C 03D5 C30000 JP $0000 ; ---@@@03D7:00->08 ; ############ DISK LOADING ############ 03D8 CDFE05 CALL $05FE ; call FDD_SPECIFY ---@@@03DA:05->0D 03DB 010900 LD BC,$0009 ; 03DE 218203 LD HL,$0382 ; copy to RAM ---@@@03E0:03->0B 03E1 110CF0 LD DE,$F00C ; 9 bytes from 0382 to F00C 03E4 EDB0 LDIR ; (8272 command opcode storage area) 03E6 CDE905 CALL $05E9 ; call SENSE DRIVE STATUS (drive number in (F00D)) <----| ---@@@03E8:05->0D 03E9 E620 AND $20 ; test bit 5 of status info (READY) | 03EB 200E JR NZ,$03FB ; if READY skip fwd ---> ---> -->| | 03ED 3A0DF0 LD A,($F00D); A=00 | | 03F0 3C INC A ; increment the drive number | | 03F1 320DF0 LD ($F00D),A; (F00D)=01 | | 03F4 FE04 CP $04 ; check all 4 drives | | 03F6 20EE JR NZ,$03E6 ; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> --->| 03F8 C30000 JP $0000 ; if no drive ready restart BOOT | ---@@@03FA:00->08 03FB CDA805 CALL $05A8 ; call RECALIBRATE <--- <--- <---| *** at this point CTC-0_INT_1 ---@@@03FD:05->0D 03FE 210080 LD HL,$8000 0401 2208F0 LD ($F008),HL ; storage addr for bytes read from 8272 by 8272_CMD 0404 01010A LD BC,$0A01 ; (B=first opcode of 8272 cmd, Read ID in FM mode, C=nr.opcodes-1) 0407 CDB304 CALL $04B3 ; call 8272_CMD_PARM (run Read ID) *** during 8272_CMD -> CTC-0_INT_2 ---@@@0409:04->0C ; *** after this point-> CTC-0_INT_1 040A 3220F0 LD ($F020),A; Read ID first result byte, ST0, AND-ed with C0h (00 = Read ID ok) 040D AF XOR A 040E 320EF0 LD ($F00E),A; (F00E)=00 (track no.) 0411 3C INC A 0412 3210F0 LD ($F010),A; (F010)=01 (sector no.) 0415 CD6305 CALL $0563 ; call PARAM_SET (prepare for Read Data) ---@@@0417:05->0D 0418 0E08 LD C,$08 ; nr of 8272 command opcodes minus 1 *** at this point -> CTC-0_INT_1 041A CDEE04 CALL $04EE ; call SEEK+CMD (Read Data) *** after SEEK -> CTC-0_INT_2 ---@@@041C:04->0C 041D C20000 JP NZ,$0000 ; if non-zero Read Data first result byte (error), restart BOOT ---@@@041F:00->08 0420 3A0080 LD A,($8000); first byte read from disk 0423 B7 OR A 0424 2808 JR Z,$042E ; if zero skip 4 lines ---> --->| 0426 FEE5 CP $E5 ; check if default value after formatting 0428 2804 JR Z,$042E ; if so skip 2 lines ---> ----->| 042A 3E02 LD A,$02 ; | 042C 1801 JR $042F ; --> -->| | 042E AF XOR A ; <--- <--- <--- <--- <--- <----| 042F 3221F0 LD ($F021),A; <-- <--| (F021)=00 if zero or formatted, 02 else 0432 CD6305 CALL $0563 ; call PARAM_SET ---@@@0434:05->0D 0435 CDBE04 CALL $04BE ; call READ_DISK ---@@@0437:04->0C 0438 CD0905 CALL $0509 ; call DIR_SEARCH ---@@@043A:05->0D 043B DA0000 JP C,$0000 ; ---@@@043D:00->08 043E 110088 LD DE,$8800 0441 ED5308F0 LD ($F008),DE ; store data bytes from 8272 at (8800) 0445 111000 LD DE,$0010 0448 19 ADD HL,DE ; addr of dir entry found in data stored at 8000, plus 10h (1-byte block addresses) 0449 7E LD A,(HL) ; addr of first block on disk for this file 044A B7 OR A ; CY flag is reset 044B 2843 JR Z,$0490 ; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> --->| 044D E5 PUSH HL 044E 2600 LD H,$00 0450 6F LD L,A ; addr of first block on disk for this file as a 16-bit value 0451 CD3005 CALL $0530 ; | ---@@@0453:05->0D 0454 3A11F0 LD A,($F011) ; bytes per sector, N 0457 B7 OR A 0458 2805 JR Z,$045F ; ---> ---> ---> ---> ---> --->| 045A 010802 LD BC,$0208 ; | BC=0208 if N not zero 045D 1803 JR $0462 ; ---> ---> ---> ---> ---> --->|---> ---> ----->| 045F 010808 LD BC,$0808 ; <--- <--- <--- <--- <--- <---| BC=0808 if N=0 | 0462 7A LD A,D ; <--- <--- <--- <--- <--- <--- <--- <--- <-----| 0463 320EF0 LD ($F00E),A ; track number 0466 D5 PUSH DE 0467 1600 LD D,00 0469 CD5905 CALL $0559 ; READ_TABLE | | ---@@@046B:05->0D 046C 3210F0 LD ($F010),A ; sector number 046F CDEE04 CALL $04EE ; SEEK+CMD | | ---@@@0471:04->0C 0472 C20000 JP NZ,$0000 ; | | ---@@@0474:00->08 0475 2A1EF0 LD HL,($F01E) 0478 2208F0 LD ($F008),HL 047B 2A1CF0 LD HL,($F01C) 047E 23 INC HL 047F D1 POP DE 0480 1C INC E 0481 7B LD A,E 0482 BD CP L 0483 DA8904 * JP C,$0489 ; | | ---@@@0485:04->0C 0486 14 INC D 0487 3E01 LD A,$01 0489 5F LD E,A 048A 10D6 DJNZ $0462 ; ---> ---> ---> ---> ---> ---> ---> ---> ----->| 048C E1 POP HL 048D 23 INC HL 048E 18B9 JR $0449 0490 21A504 LD HL,$04A5 ; <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <---| ---@@@0492:04->0C 0493 1100E0 LD DE,$E000 0496 010E00 LD BC,$000E 0499 EDB0 LDIR 049B 2100E0 LD HL,$E000 049E 3E40 LD A,$40 04A0 D3FE OUT ($FE),A ; set "O6" to 1 (for CP/M config) 04A2 ED4F LD R,A ; reset bit 7 of R (change to CP/M config) 04A4 E9 JP (HL) 04A5 210088 LD HL,$8800 ; this code is relocated 04A8 110001 LD DE,$0100 ; at E000 and executed 04AB 010050 LD BC,$5000 ; from there by the 04AE EDB0 LDIR ; instructions above 04B0 C30001 JP $0100 ; (lines 0490 to 04A4) ; ; ######### 8272_CMD_PARM ########### ; --- input: B = first 8272 opcode 04B3 78 LD A,B ; A=0A (see line 404) 04B4 320CF0 LD ($F00C),A; (F00C)=0A (first byte of 8272 command - Read ID in FM mode) 04B7 21BA06 LD HL,$06BA ; CTC-0_INT_2 (for Result-Phase commands) ---@@@04B9:06->0E 04BA CD4706 CALL $0647 ; call 8272_CMD ---@@@04BC:06->0E 04BD C9 RET ; ######### READ_DISK ############### ; ---input: A = 00 if FM, 02 if MFM 04BE B7 OR A 04BF 2805 JR Z,$04C6 ; --->| 00 if FM, 02 if MFM 04C1 010804 LD BC,$0408 ; | BC=0408 if MFM (B=nr.of loops, C=nr.of 8272 opcodes-1) 04C4 1803 JR $04C9 ; --->|--->| 04C6 010810 LD BC,$1008 ; <---| | BC=1008 if FM (B=nr.of loops, C=nr.of 8272 opcodes-1) 04C9 3A21F0 LD A,($F021); <--- <---| 04CC 320EF0 LD ($F00E),A; track no. in (F00E) for SEEK+CMD 04CF 3E01 LD A,$01 ; initial displacement to read from in table for READ_TABLE 04D1 F5 PUSH AF ; <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <---| 04D2 5F LD E,A ; | 04D3 1600 LD D,$00 ; | 04D5 CD5905 CALL $0559 ; call READ_TABLE, read from displacement in A | ---@@@04D7:05->0D 04D8 3210F0 LD ($F010),A; store in (F010) - sector number | 04DB CDEE04 CALL $04EE ; call SEEK+CMD (Read Data, (F00C) set at line 0415) | ---@@@04DD:04->0C 04DE 200B * JR NZ,$04EB ; restart BOOT if Read Data finished w err | 04E0 2A1EF0 LD HL,($F01E) ; storage addr for next read from disk (see 8272_CMD) | 04E3 2208F0 LD ($F008),HL ; (F008+F009) = dest addr for next data from FDD | 04E6 F1 POP AF ; | 04E7 3C INC A ; | 04E8 10E7 DJNZ $04D1 ; 4 loops if MFM, 16 if FM ---> ---> ---> ---> ---> --->| 04EA C9 RET 04EB C30000 * JP $0000 ; ---@@@04ED:00->08 ; ######### SEEK+CMD ######### ; *** SEEK on specified drive to specified track and then run an 8272 command ; --- input: C = nr. of 8272 opcodes - 1 ; --- input: (F00C) = first 8272 opcode for 8272_CMD ; --- input: (F00D) = drive number to SEEK ; --- input: (F00E) = track number to SEEK ; --- output: A=0 if ok, A nonzero if err ; --- output: Z flag set if ok, reset if err 04EE C5 PUSH BC 04EF CDB905 CALL $05B9 ; call SEEK, (F00D)=drive number, (F00E)=track number ---@@@04F1:05->0D 04F2 C1 POP BC 04F3 1E0A LD E,$0A 04F5 C5 PUSH BC ; <--- <--- <--- <--- <--| 04F6 D5 PUSH DE ; | 04F7 21BA06 LD HL,$06BA ; CTC-0_INT_2 | (for Result-Phase commands) ---@@@04F9:06->0E 04FA CD4706 CALL $0647 ; call 8272_CMD | ---@@@04FC:06->0E 04FD D1 POP DE ; | 04FE C1 POP BC ; | 04FF C8 RET Z ; return if 8272_CMD err | 0500 1D DEC E ; | 0501 20F2 JR NZ,$04F5 ; --> ---> ---> ---> --->| 0503 3A15F0 LD A,($F015); 8272_CMD first result data byte, ST0 0506 E6C0 AND $C0 ; test bits 6, 7 (Command Termination code) 0508 C9 RET ; ############### DIR_SEARCH ################### ; *** search for dir entry stored at 03AF in the directory read from disk at 8000 ; --- output: Z flag set if dir entry found ; --- output: HL = addr of dir entry found in data stored at 8000 0509 210080 LD HL,$8000 ; address of bytes read from FDD 050C 11AF03 LD DE,$03AF ; ---@@@050E:03->0B 050F 0640 LD B,$40 ; search 64 consecutive directory entries 0511 CD1F05 CALL $051F ; call STR_COMP <--- <--- <--- <--- <--- <--- <--- <--- <---| ---@@@0513:05->0D 0514 C8 RET Z ; return if strings equal | ; | 0515 D5 PUSH DE 0516 112000 LD DE,$0020 0519 19 ADD HL,DE ; increment HL by 20h (32), length of one dir entry 051A D1 POP DE 051B 10F4 DJNZ $0511 ; ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> --->| 051D 37 SCF 051E C9 RET ; ############### STR_COMP ##################### ; *** compare 12 bytes from (DE) with 12 bytes from (HL) 051F E5 PUSH HL 0520 D5 PUSH DE 0521 C5 PUSH BC 0522 060C LD B,$0C 0524 1A LD A,(DE) ; <--- <--- <--- <--- <---| 0525 BE CP (HL) ; compare (DE) with (HL) | 0526 2004 JR NZ,$052C ; exit loop if different | 0528 23 INC HL ; | 0529 13 INC DE ; | 052A 10F8 DJNZ $0524 ; ---> ---> ---> ---> --->| 052C C1 POP BC 052D D1 POP DE 052E E1 POP HL 052F C9 RET ; returns Z if strings equal, NZ if different ; ############# 0530 01FF03 LD BC,$03FF ; B=03 for 3 loops, C=FF for counting from 0 up 0533 CB25 SLA L ; <--- <--- <--- <--- <-| 0535 CB14 RL H ; HL = HL * 2 | 0537 10FA DJNZ $0533 ; HL = HL * 8 ---> ---->| 0539 23 INC HL ; HL = HL + 1 >>> HL=HL*8+1 053A ED5B1CF0 LD DE,($F01C) ; 1A if FM or 28 if MFM (set in PARAM_SET) 053E 0C INC C ; C = C + 1 <--- <--- <--- <--- <--- <---| 053F ED52 SBC HL,DE ; HL = HL-(1A if FM or 28 if MFM)-CY | 0541 30FB JR NC,$053E ; ---> ---> ---> ---> ---> ---> ---> --->| 0543 19 ADD HL,DE 0544 3A11F0 LD A,($F011) ; bytes per sector, N 0547 B7 OR A 0548 2808 JR Z,$0552 ; ---> ---> ---> ---> ---> ---> ---> --->| 054A 7D LD A,L ; | 054B 3D DEC A ; | 054C CB3F SRL A ; | 054E CB3F SRL A ; | 0550 3C INC A ; | 0551 6F LD L,A ; L = (L-1)/4 + 1 | 0552 3A21F0 LD A,($F021) ; <--- <--- <--- <--- <--- <--- <--- <--| 0555 81 ADD A,C 0556 57 LD D,A ; track 0557 5D LD E,L 0558 C9 RET ; ############### READ_TABLE ################### ; --- input: IX = table base ; --- input: DE = displacement ; --- output: A = byte read 0559 DDE5 PUSH IX 055B DD19 ADD IX,DE 055D DD7E00 LD A,(IX+$00) 0560 DDE1 POP IX 0562 C9 RET ; ############### PARAM_SET #################### ; *** prepare parameters for next 8272 command (Read Data) ; --- input: (F020) = 00 if prev.Read ID in FM successfull, nonzero if not (ST0 AND C0h) 0563 AF XOR A 0564 321DF0 LD ($F01D),A; (F01D)=00 0567 3A20F0 LD A,($F020); 00 if Read ID in FM successfull, nonzero if not (ST0 AND C0h) 056A B7 OR A 056B 281F JR Z,$058C ; if (F020)=00 ---> ---> ---> ->| 056D 3E46 LD A,$46 ; | 056F 320CF0 LD ($F00C),A; (F00C)=46 (Read Data MFM) | 0572 3E0A LD A,$0A ; | 0574 3212F0 LD ($F012),A; (F012)=0A (EOT) | 0577 3E28 LD A,$28 ; | 0579 321CF0 LD ($F01C),A; (F01C)=28 | 057C DD21A403 LD IX,$03A4 ; MFM XLT table base | ---@@@057F:03->0B 0580 210200 LD HL,$0002 ; | 0583 220AF0 LD ($F00A),HL ; (F00A)=02 (CTC2 TC), (F00B)=00 (CTC1 TC) -> 2x256=512B/sect 0586 3E02 LD A,$02 ; | 0588 3211F0 LD ($F011),A; (F011)=02 (N) | 058B C9 RET ; | ; | 058C 3E06 LD A,$06 ; <--- <--- <--- <--- <--- <----| 058E 320CF0 LD ($F00C),A; (F00C)=06 (Read Data FM) 0591 3E1A LD A,$1A 0593 3212F0 LD ($F012),A; (F012)=1A (EOT) 0596 321CF0 LD ($F01C),A; (F01C)=1A 0599 DD218A03 LD IX,$038A ; FM XLT table base ---@@@059C:03->0B 059D 210180 LD HL,$8001 05A0 220AF0 LD ($F00A),HL ; (F00A)=01 (CTC2 TC), (F00B)=80 (CTC1 TC) -> 1x128=128B/sect 05A3 AF XOR A 05A4 3211F0 LD ($F011),A; (F011)=00 (N) 05A7 C9 RET ; ############### RECALIBRATE ################## ; *** must be used with int. vector CTC-0_INT_1 ; --- input: (F00D) = drive number ; --- output: (F015) = Seek result byte 1 of 2 (ST0) ; --- output: (F016) = Seek result byte 2 of 2 (PCN) 05A8 CDD205 CALL $05D2 ; call FDD_READY ---@@@05AA:05->0D 05AB 3E07 LD A,$07 ; 8272 Recalibrate command - byte 1 of 2 05AD D3FD OUT ($FD),A ; send to 8272 05AF CD1A06 CALL $061A ; call 8272_READY ---@@@05B1:06->0E 05B2 3A0DF0 LD A,($F00D); 8272 Recalibrate command - byte 2 of 2 (drive number) 05B5 D3FD OUT ($FD),A ; send to 8272 05B7 76 HALT ; wait for interrupt (int. vector must be CTC-0_INT_1) 05B8 C9 RET ; ############### SEEK ######################### ; *** must be used with int. vector CTC-0_INT_1 ; --- input: (F00D) = drive number ; --- input: (F00E) = track number ; --- output: (F015) = Seek result byte 1 of 2 (ST0) ; --- output: (F016) = Seek result byte 2 of 2 (PCN) 05B9 CDD205 CALL $05D2 ; call FDD_READY ---@@@05BB:05->0D 05BC 3E0F LD A,$0F ; 8272 Seek command - byte 1 of 3 05BE D3FD OUT ($FD),A ; send to 8272 05C0 CD1A06 CALL $061A ; call 8272_READY ---@@@05C2:06->0E 05C3 3A0DF0 LD A,($F00D); 8272 Seek command - byte 2 of 3 (drive number) 05C6 D3FD OUT ($FD),A ; send to 8272 05C8 CD1A06 CALL $061A ; call 8272_READY ---@@@05CA:06->0E 05CB 3A0EF0 LD A,($F00E); 8272 Seek command - byte 3 of 3 (cyl number to go to) 05CE D3FD OUT ($FD),A ; send to 8272 05D0 76 HALT ; wait for interrupt (int. vector must be CTC-0_INT_1) 05D1 C9 RET ; ############### FDD_READY #################### 05D2 CDE905 CALL $05E9 ; call SENSE_DRIVE_STATUS ---@@@05D4:05->0D 05D5 E620 AND $20 ; test bit 5 of status (result) byte (FDD Ready) 05D7 2003 JR NZ,$05DC ; if ready skip next line 05D9 C30000 JP $0000 ; restart this BOOT code ---@@@05DB:00->08 05DC CD2006 CALL $0620 ; call CTC_INIT ---@@@05DE:06->0E 05DF 219C06 LD HL,$069C ; ---@@@05E1:06->0E 05E2 2200F0 LD ($F000),HL ; CTC-0 int. vector to 069C (CTC-0_INT_1) 05E5 CD1406 CALL $0614 ; call FDD+8272_READY ---@@@05E7:06->0E 05E8 C9 RET ; ############### SENSE_DRIVE_STATUS ########### ; --- input: (F00D) = drive number, head ; --- output: A = Sense Drive Status result (ST3) 05E9 CD1406 CALL $0614 ; call FDD+8272_READY ---@@@05EB:06->0E 05EC 3E04 LD A,$04 ; Sense Drive Status command - byte 1 of 2 05EE D3FD OUT ($FD),A ; send to 8272 05F0 CD1A06 CALL $061A ; call 8272 READY ---@@@05F2:06->0E 05F3 3A0DF0 LD A,($F00D); Sense Drive Status command - byte 2 of 2 (00, drive 0 Head 0) 05F6 D3FD OUT ($FD),A ; send to 8272 05F8 CD1A06 CALL $061A ; call 8272 READY ---@@@05FA:06->0E 05FB DBFD IN A,($FD) ; read 8272 data (status info) 05FD C9 RET ; ############### FDD_SPECIFY ################## 05FE CD1406 CALL $0614 ; call FDD+8272_READY ---@@@0600:06->0E 0601 3E03 LD A,$03 ; Specify Command - byte 1 of 3 0603 D3FD OUT ($FD),A ; send to 8272 0605 CD1A06 CALL $061A ; call 8272 READY ---@@@0607:06->0E 0608 3E3F LD A,$3F ; Specify Command - byte 2 of 3 (SRT=13 ms, HUT=240 ms) 060A D3FD OUT ($FD),A ; send to 8272 060C CD1A06 CALL $061A ; call 8272 READY ---@@@060E:06->0E 060F 3E17 LD A,$17 ; Specify Command - byte 3 of 3 (HLT=30 ms, Non-DMA mode) 0611 D3FD OUT ($FD),A ; send to 8272 0613 C9 RET ; ############### FDD+8272_READY ############### 0614 DBF5 IN A,($F5) ; Read 8272 Status Register 0616 E61F AND $1F ; test bits 0 1 2 3 4 (drives in Seek Mode or Read/Write Command in progress) 0618 20FA JR NZ,$0614 ; if Seek or Read/Write in progress go back 2 lines 061A DBF5 IN A,($F5) ; Read 8272 Status Reg ###### 8272_READY ####### 061C 07 RLCA ; test bit 7 (RQM - if Data register ready to send/receive) 061D 30FB JR NC,$061A ; if not ready, go back 2 lines 061F C9 RET ; ############### CTC_INIT ################# ; --- input: (F00A) = CTC-2 Time Constant ; --- input: (F00B) = CTC-1 Time Constant 0620 F3 DI 0621 ED5E IM 2 0623 2100F0 LD HL,$F000 ; interrupt vector table base 0626 7C LD A,H 0627 ED47 LD I,A ; I=F0 upper half of int. vector 0629 7D LD A,L ; A=00 062A D3E3 OUT ($E3),A ; CTC Channel 0, specify int. vector = 00000cc0 ; Interrupt service routine addresses are located at: ; CTC-0 -> F000, CTC-1 -> F002, CTC-2 -> F004, CTC-3 -> F006 062C 3EDF LD A,$DF ; 062E D3E3 OUT ($E3),A ; CTC-0 Enable Int. Counter Mode, Rising Edge, Time Constant Follows 0630 3E01 LD A,$01 ; Time Constant 1 0632 D3E3 OUT ($E3),A ; CTC-0 set to count to 1 0634 2A0AF0 LD HL,($F00A) 0637 3E5F LD A,$5F ; 0639 D3EB OUT ($EB),A ; CTC-1 Disable Int, Counter Mode, Rising Edge, Time Constant Follows 063B 7C LD A,H ; Time Constant from (F00B) 063C D3EB OUT ($EB),A ; send to CTC-1 063E 3E5F LD A,$5F ; 0640 D3F3 OUT ($F3),A ; CTC-2 Disable Int, Counter Mode, Rising Edge, Time Constant Follows 0642 7D LD A,L ; Time Constant from (F00A) 0643 D3F3 OUT ($F3),A ; send to CTC-2 0645 FB EI 0646 C9 RET ; ############# 8272_CMD ############# ; --- input: HL = CTC-0 int. vector (must be CTC-0_INT_2) ; --- input: C = nr. of 8272 opcodes - 1 ; --- input: (F00C) = first 8272 opcode ; --- input: (F008) = storage start addr for bytes read from 8272 ; --- output: (F01E-F01F) = current storage addr for next byte read from disk after this command ; --- output: (F015-F01B) = 8272 command result (status) bytes ; --- output: A = 00 if command terminated ok, nonzero if terminated abnormally ; --- output: Z flag = 1 if command terminated ok, 0 if terminated abnormally 0647 2200F0 LD ($F000),HL ; CTC-0 int. service routine addr 064A CD2006 CALL $0620 ; CTC INIT ---@@@064C:06->0E 064D 2A08F0 LD HL,($F008) ; storage start addr for bytes read from 8272 0650 110CF0 LD DE,$F00C ; addr of first 8272 opcode 0653 CD1406 CALL $0614 ; CALL FDD+8272_READY ---@@@0655:06->0E 0656 CD1A06 CALL $061A ; CALL 8272_READY <--- <--- <--- <--- <-| ---@@@0658:06->0E 0659 1A LD A,(DE) ; | 065A D3FD OUT ($FD),A ; send opcode to 8272 | 065C 13 INC DE ; points to next opcode | 065D 0D DEC C ; opcode counter | 065E 20F6 JR NZ,$0656 ; if not zero ---> ---> ---> ---> ----->| 0660 CD1A06 CALL $061A ; call 8272_READY ---@@@0662:06->0E 0663 1A LD A,(DE) ; last 8272 opcode 0664 0620 LD B,$20 ; filter for bit 5 of status info of 8272 command 0666 0EFD LD C,$FD ; port address for INI instruction in CTC-0_INT_2 0668 D3FD OUT ($FD),A ; send last opcode to 8272 066A 76 HALT ; wait for first interrupt from Z80-CTC (signaling non-DMA byte transfer (Exec Phase) or begin of Result Phase) 066B DBF5 IN A,($F5) ; read 8272 Status Register <--- <--- <--- <----| 066D A0 AND B ; filter bit 5 of status info (B=20) | (the Non-DMA bit) 066E C26B06 * JP NZ,$066B ; if bytes still transferring from FDD ---> --->| jump if still in Exec Phase ---@@@0670:06->0E 0671 0600 LD B,$00 0673 10FE DJNZ $0673 ; repeat this DJNZ 256 times (256 x 13T = 0.9ms) ***during this the int. at begin of Result Phase occurs*** 0675 2B DEC HL ; HL points to first status byte read from 8272 (HL=F007 if CTC-0_INT_1) 0676 221EF0 LD ($F01E),HL ; (F01E-F01F)=addr of first status byte from 8272 (F007 if CTC-0_INT_1) 0679 7E LD A,(HL) ; A=the first status byte read from 8272 (A=(F007) if CTC-0_INT_1) 067A 2115F0 LD HL,$F015 067D 77 LD (HL),A ; (F015)=the first status byte read from 8272 (or =(F007) if CTC-0_INT_1) 067E 23 INC HL ; HL=F016 067F CD1A06 CALL $061A ; call 8272_READY <--- <--- <---| ---@@@0681:06->0E 0682 DBFD IN A,($FD) ; read 8272 status data | 0684 77 LD (HL),A ; (F016)=8272 status byte | the status bytes from 8272 0685 23 INC HL ; HL=F017 | are saved from F015 up (if CTC-0_INT_2) 0686 0600 LD B,$00 ; | and (F015)=first status byte 0688 10FE DJNZ $0688 ; repeat this DJNZ 256 times | 068A DBF5 IN A,($F5) ; read 8272 Status Register | 068C E610 AND $10 ; test bit 4 (FDC Busy) | 068E 20EF JR NZ,$067F ; ---> ---> ---> ---> ---> ---->| 0690 219C06 LD HL,$069C ; ---@@@0692:06->0E 0693 2200F0 LD ($F000),HL ; change to CTC-0_INT_1 (for non-Result-Phase commands) 0696 3A15F0 LD A,($F015); the first status byte read from 8272 0699 E6C0 AND $C0 ; test bits 6,7 (Normal Termination of Command, s/b 0) 069B C9 RET ; ############# CTC-0_INT_1 ############## ; *** for SEEK and RECALIBRATE commands (that don't have a Result phase) ; --- output: (F015) = result byte 1 (ST0) ; --- output: (F016) = result byte 2 (PCN) 069C F5 PUSH AF 069D E5 PUSH HL 069E 2115F0 LD HL,$F015 06A1 CD1A06 CALL $061A ; call 8272 READY ---@@@06A3:06->0E 06A4 3E08 LD A,$08 ; 8272 opcode (Sense Int. Status)... 06A6 D3FD OUT ($FD),A ; ...sent to 8272 06A8 CD1A06 CALL $061A ; call 8272 READY ---@@@06AA:06->0E 06AB DBFD IN A,($FD) ; result byte 1 of 2... 06AD 77 LD (HL),A ; ...stored at (F015) (ST0) 06AE 23 INC HL 06AF CD1A06 CALL $061A ; call 8272 READY ---@@@06B1:06->0E 06B2 DBFD IN A,($FD) ; result byte 2 of 2... 06B4 77 LD (HL),A ; ...stored at (F016) (PCN) 06B5 E1 POP HL 06B6 F1 POP AF 06B7 FB EI 06B8 ED4D RETI ; ############# CTC-0_INT_2 ############## ; *** for commands other than SEEK and RECALIBRATE (that have a Result phase) 06BA EDA2 INI 06BC 04 INC B ; B maintained at initial value (it is incremented during INI) 06BD FB EI 06BE ED4D RETI ; ############### BASIC LOADING ################# 06C0 010020 LD BC,$2000 ; load BASIC, 06C3 110080 LD DE,$8000 ; 06C6 210040 LD HL,$4000 ; 06C9 EDB0 LDIR ; half at 8000-9FFF 06CB 010020 LD BC,$2000 ; 06CE 1100E0 LD DE,$E000 ; 06D1 210060 LD HL,$6000 ; 06D4 EDB0 LDIR ; and half at E000-FFFF 06D6 210000 LD HL,$0000 ; jump addr in BASIC config 06D9 AF XOR A 06DA D3FE OUT ($FE),A ; border black, "O5"="O6"=0 06DC ED4F LD R,A ; reset bit 7 of R 06DE E9 JP (HL) ; jump to BASIC start ; ############## END BASIC LOADING ############## 06DF 3100C0 LD SP,$C000 06E2 37 SCF 06E3 DD210080 LD IX,$8000 06E7 110020 LD DE,$2000 06EA 3EFE LD A,$FE 06EC CD3A07 CALL $073A ; ---@@@06EE:07->0F 06EF D20000 JP NC,$0000 06F2 DD2100E0 LD IX,$E000 06F6 110020 LD DE,$2000 06F9 37 SCF 06FA 3EFE LD A,$FE 06FC CD3A07 CALL $073A ; ---@@@06FE:07->0F 06FF D20000 JP NC,$0000 ; ---@@@0701:00->08 0702 C3D606 JP $06D6 ; ---@@@0704:06->0E 0705 1F RRA ; test column K0 ("SPACE" "Q" "A" "CS") 0706 DA1007 JP C,$0710 ; if key pressed skip next 3 lines ---> --->| ---@@@0708:07->0F 0709 3E02 LD A,$02 ; | 070B ED79 OUT (C),A ; write "02" to port C 8255 (border red) <------| 070D C3C006 JP $06C0 ; jump to BASIC LOADING | | ---@@@070F:06->0E 0710 1F RRA ; test column K1 ("SS" "W" "S" "Z") <--- <--| | 0711 DAB700 JP C,$00B7 ; if key pressed, go back to beginning | ---@@@0713:00->08 0714 3E05 LD A,$05 ; if not, A=05 (border=cyan) | 0716 C30B07 JP $070B ; ---> ---> ---> ---> ---> ---> ---> ---> ----->| ---@@@0718:07->0F 0719 3E04 LD A,$04 ; border green 071B ED79 OUT (C),A 071D C3C006 JP $06C0 ; jump to BASIC LOADING ---@@@071F:06->0E 0720 07 RLCA 0721 DAC006 JP C,$06C0 ; ---@@@0723:06->0E 0724 DDE5 PUSH IX 0726 F1 POP AF 0727 E63F AND 3F 0729 CB3F SRL A 072B CB3F SRL A 072D CB3F SRL A 072F 5F LD E,A 0730 1600 LD D,$00 0732 218CDA LD HL,$DA8C 0735 19 ADD HL,DE 0736 CBFE SET 7,(HL) 0738 18FE JR $0738 ; ######### 073A 14 INC D 073B 08 EX AF,AF' 073C 15 DEC D 073D F3 DI 073E 3E0F LD A,$0F 0740 D3FE OUT ($FE),A ; border=white, Tape Out=1 0742 DBFE IN A,($FE) ; read keyboard + Tape In 0744 1F RRA 0745 E620 AND $20 ; test bit 5 (Tape In shifted) 0747 F602 OR $02 ; set bit 1 0749 4F LD C,A 074A BF CP A 074B C0 RET NZ 074C CDC707 CALL $07C7 ; ---@@@074E:07->0F 074F 30FA JR NC,$074B 0751 211504 LD HL,$0415 0754 10FE DJNZ $0754 0756 2B DEC HL 0757 7C LD A,H 0758 B5 OR L 0759 20F9 JR NZ,$0754 075B CDC307 CALL $07C3 ; ---@@@075D:07->0F 075E 30EB JR NC,$074B 0760 069C LD B,$9C 0762 CDC307 CALL $07C3 ; ---@@@0764:07->0F 0765 30E4 JR NC,$074B 0767 3EC6 LD A,$C6 0769 B8 CP B 076A 30E0 JR NC,$074C 076C 24 INC H 076D 20F1 JR NZ,$0760 076F 06C9 LD B,$C9 0771 CDC707 CALL $07C7 ; ---@@@0773:07->0F 0774 30D5 JR NC,$074B 0776 78 LD A,B 0777 FED4 CP $D4 0779 30F4 JR NC,$076F 077B CDC707 CALL $07C7 ; ---@@@077D:07->0F 077E D0 RET NC 077F 79 LD A,C 0780 EE03 XOR $03 0782 4F LD C,A 0783 2600 LD H,$00 0785 06B0 LD B,$B0 0787 181F JR $07A8 0789 08 EX AF,AF' 078A 2007 JR NZ,$0793 078C 300F JR NC,$079D 078E DD7500 LD (IX+$00),L 0791 180F JR $07A2 0793 CB11 RL C 0795 AD XOR L 0796 C0 RET NZ 0797 79 LD A,C 0798 1F RRA 0799 4F LD C,A 079A 13 INC DE 079B 1807 JR $07A4 079D DD7E00 LD A,(IX+$00) 07A0 AD XOR L 07A1 C0 RET NZ 07A2 DD23 INC IX 07A4 1B DEC DE 07A5 08 EX AF,AF' 07A6 06B2 LD B,$B2 07A8 2E01 LD L,$01 07AA CDC307 CALL $07C3 ; ---@@@07AC:07->0F 07AD D0 RET NC 07AE 3ECB LD A,$CB 07B0 B8 CP B 07B1 CB15 RL L 07B3 06B0 LD B,$B0 07B5 D2AA07 JP NC,$07AA ; ---@@@07B7:07->0F 07B8 7C LD A,H 07B9 AD XOR L 07BA 67 LD H,A 07BB 7A LD A,D 07BC B3 OR E 07BD 20CA JR NZ,$0789 07BF 7C LD A,H 07C0 FE01 CP 01 07C2 C9 RET 07C3 CDC707 CALL $07C7 ; ---@@@07C5:07->0F 07C6 D0 RET NC ; return if SPACE pressed ; ########### DELAY + TAPE IN TEST ########### 07C7 3E16 LD A,$16 ; for 07C9 3D DEC A ; delay 07CA 20FD JR NZ,$07C9 ; purposes 07CC A7 AND A ; CY flag reset 07CD 04 INC B ; <--- <--- <--- <--- <--- <----| 07CE C8 RET Z ; return if B=00 | ; | 07CF 3E7F LD A,$7F ; test keyboard row KA15 | 07D1 DBFE IN A,($FE) ; read keyboard | 07D3 1F RRA ; test column K0 ("SPACE" key) | 07D4 D0 RET NC ; return if pressed | ; | 07D5 A9 XOR C ; A xor C | 07D6 E620 AND $20 ; test bit 5 of A (Tape Input) | 07D8 28F3 JR Z,$07CD ; if zero ---> ---> ---> ---> --> 07DA 79 LD A,C 07DB 2F CPL 07DC 4F LD C,A ; invert C 07DD E607 AND $07 ; filter bits 0, 1, 2 07DF F608 OR $08 ; set bit 3 07E1 D3FE OUT ($FE),A 07E3 37 SCF ; CY=1 07E4 C9 RET 07E5 30E4 JR NC,07CB 07E7 3EC6 LD A,C6 07E9 B8 CP B 07EA 30E0 JR NC,07CC 07EC 24 INC H 07ED 20F1 JR NZ,07E0 07EF 06C9 LD B,C9 07F1 CDC707 CALL 07C7 ; ---@@@07F3:07->0F 07F4 30D5 JR NC,07CB 07F6 78 LD A,B 07F7 FED4 CP D4 07F9 30F4 JR NC,07EF 07FB CDC707 CALL 07C7 ; ---@@@07FD:07->0F 07FE D0 RET NC 07FF 79 LD A,C